﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Xna.Framework.Media;
using System.IO;
using Microsoft.Phone;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using Microsoft.Phone.Tasks;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using Coding4Fun.Toolkit.Controls;

namespace MultiPhotoChooser
{
    public partial class MediaLibraryPage : PhoneApplicationPage
    {
        PictureAlbum cameraRoll = null;
        //PictureAlbum savedPics = null;
        //PictureAlbum photoAlbums = null;
        
        PictureItemList cameraRollImages = null;
        //PictureItemList savedPicsImages = null;
        PictureItemList albumImages = null;

        PictureItemList selectedPics = null;

        SolidColorBrush phoneAccentBrush = (SolidColorBrush)Application.Current.Resources["PhoneAccentBrush"];

        SolidColorBrush phoneBackgroundBrush = (SolidColorBrush)Application.Current.Resources["PhoneBackgroundBrush"];

        DispatcherTimer timer = new DispatcherTimer { Interval = new TimeSpan(2000) };

        public bool IsLoading = false;
        
        private object o = new object();

        private int _SelectionLimit = 0;

        private int _currentIndex = 0;

        private int _loadThreadhold = 20;
        public int SelectionLimit {
            get
            {
                return _SelectionLimit;
            }
            set
            {
                if (value != _SelectionLimit)
                    _SelectionLimit = value;
            }
        }

        public delegate void OnCompleteEventHandler(object sender, MultiPhotoResult e);

        public event OnCompleteEventHandler SelectComplete;

        protected virtual void OnSelectComplete(MultiPhotoResult e)
        {
            if (SelectComplete != null)
            {
                SelectComplete(this, e);
            }         
        }

        public MediaLibraryPage()
        {
            InitializeComponent();
            Loaded+=MediaLibraryPage_Loaded;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
        }

        private void MediaLibraryPage_Loaded(object sender, RoutedEventArgs e)
        {
            Initialize_UI();
        }

        private void lls_camera_roll_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //Don't do add or remove if the pivot is on index 0
            if (pivot.SelectedIndex == 0)
                return;

            if (e.AddedItems.Count > 0)
            {
                var p = e.AddedItems[0] as PictureItem;

                AddPicSampleItem(sender, p);
            }

            if (e.RemovedItems.Count > 0)
            {
                var p = e.RemovedItems[0] as PictureItem;
                RemovePicSampleItem(p);
            }
        }

        private void lls_saved_picture_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //if (e.RemovedItems.Count > 0)
            //{
            //    var p = e.RemovedItems[0] as PictureItem;
            //    RemovePicSampleItem(p);
            //}
        }

        private void AddPicSampleItem(object sender, PictureItem p)
        {

            if ((selectedPics.Items.Exists(x => x.Date.Equals(p.Date))) == true)
                return;

            if (selectedPics.Items.Count < _SelectionLimit || _SelectionLimit == 0)
            {
                selectedPics.Items.Add(p);
                SetSelectionCount();
            }
            else
            {
                MessageBox.Show("You have reached selection limit: "+SelectionLimit);
                var lls = sender as LongListMultiSelector;
                lls.SelectedItems.Remove(p);
            }
        }

        private void RemovePicSampleItem(PictureItem p)
        {
            PictureItem picture = selectedPics.Items.Find(x => x.Date.Equals(p.Date));
            selectedPics.Items.Remove(picture);
            SetSelectionCount();
        }

        private void btnSubmit_Click(object sender, RoutedEventArgs e)
        {
            if (selectedPics.Items.Count == 0)
            {
                MessageBox.Show("Please select a photo to submit!");
                return;
            }

            MultiPhotoResult args = new MultiPhotoResult();
            args.ChosenPhotoList = selectedPics.Items;
            args.TaskResult = Microsoft.Phone.Tasks.TaskResult.OK;

            OnSelectComplete(args);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //Button b = sender as Button;

            //if (b.CommandParameter.Equals("CameraRoll"))
            //{
            //    //CameraRoll
            //    lls_camera_roll.Visibility = Visibility.Visible;
            //    lls_saved_picture.Visibility = Visibility.Collapsed;


            //    btnCameraRoll.Background = phoneAccentBrush;
            //    btnSavedPicture.Background = phoneBackgroundBrush;
            //}
            //else
            //{
            //    ////SavedPics
            //    //lls_camera_roll.Visibility = Visibility.Collapsed;
            //    //lls_saved_picture.Visibility = Visibility.Visible;

            //    //btnCameraRoll.Background = phoneBackgroundBrush;
            //    //btnSavedPicture.Background = phoneAccentBrush;
            //}
        }

        private void ResetUI()
        {
            //lls_albums.Visibility = Visibility.Visible;
            //lls_camera_roll.Visibility = Visibility.Collapsed;
            //lls_saved_picture.Visibility = Visibility.Collapsed;

            //btnCameraRoll.Background = phoneAccentBrush;
            //btnSavedPicture.Background = phoneBackgroundBrush;

            //lls_camera_roll.SelectedItems.Clear();
            //lls_saved_picture.SelectedItems.Clear();
            //selectedPics.Items.Clear();

            //tb_count.Text = "0";
        }

        private void Initialize_UI()
        {                       
            cameraRoll = null;

            new Thread(() =>
            {
                if (cameraRollImages == null)
                    cameraRollImages = new PictureItemList();

                if (albumImages == null)
                    albumImages = new PictureItemList();

                if (selectedPics == null)
                    selectedPics = new PictureItemList();

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    lls_saved_picture.ItemsSource = selectedPics.Items;
                });

                MediaLibrary ml = null;

                foreach (MediaSource source in MediaSource.GetAvailableMediaSources())
                {
                    if (source.MediaSourceType == MediaSourceType.LocalDevice)
                    {
                        ml = new MediaLibrary(source);
                        PictureAlbumCollection allAlbums = ml.RootPictureAlbum.Albums;
                        
                        MakePhotoAlbum(allAlbums);
                    }
                }

            }).Start();
        }

        private void MakePhotoAlbum(PictureAlbumCollection allAlbums)
        {
            Dispatcher.BeginInvoke(() =>
            {
                foreach (var album in allAlbums)
                {
                    if (album.Pictures.Count > 0)
                    {
                        var p = album.Pictures[album.Pictures.Count - 1];
                        BitmapImage b = new BitmapImage();
                        b = new BitmapImage();
                        b.SetSource(p.GetImage());

                        if (b.PixelHeight > b.PixelWidth)
                            b.DecodePixelWidth = 250;
                        else
                            b.DecodePixelHeight = 250;

                        albumImages.Items.Add(
                            new PictureItem
                            {
                                ThumbUrl = b,
                                OriginalFileName = album.Name,
                            });
                    }
                }
                lls_albums.ItemsSource = albumImages.Items;
            });
        }

        private void SetSelectionCount()
        {
            int count = selectedPics.Items.Count;
            tb_count.Text = count.ToString();
        }

        private void lls_albums_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems[0] != null)
            {
                PictureItem pic = e.AddedItems[0] as PictureItem;
                string albumName = pic.OriginalFileName;

                LoadAlbumByName(albumName);
            }
            lls_albums.SelectedItem = null;
        }

        private void LoadAlbumByName(string albumName)
        {
            lls_camera_roll.ItemsSource = null;
            progressString.Visibility = System.Windows.Visibility.Visible;

            pivot.SelectedIndex = 1;

            new Thread(() =>
            {
                MediaLibrary ml = null;
                cameraRollImages.Items.Clear();

                foreach (MediaSource source in MediaSource.GetAvailableMediaSources())
                {
                    if (source.MediaSourceType == MediaSourceType.LocalDevice)
                    {
                        ml = new MediaLibrary(source);
                        PictureAlbumCollection allAlbums = ml.RootPictureAlbum.Albums;

                        foreach (PictureAlbum album in allAlbums)
                        {
                            if (album.Name == albumName)
                            {
                                cameraRoll = album;
                            }
                        }

                        if (cameraRoll != null)
                        {
                            Dispatcher.BeginInvoke(() =>
                            {
                                _currentIndex = cameraRoll.Pictures.Count;

                                int loopCount = 0;

                                //if (_currentIndex >= _loadThreadhold)
                                //    loopCount = _currentIndex - _loadThreadhold;
                                //else
                                //    loopCount = _currentIndex - 1;

                                if (_currentIndex <= _loadThreadhold)
                                {
                                    loopCount = - 1;
                                }
                                else
                                {
                                    loopCount = _currentIndex - _loadThreadhold;
                                }

                                for (int i = _currentIndex - 1; i > loopCount; i--)
                                {
                                    Picture p = cameraRoll.Pictures[i];
                                    BitmapImage b = new BitmapImage();
                                    b = new BitmapImage();
                                    b.CreateOptions = BitmapCreateOptions.BackgroundCreation;
                                    b.SetSource(p.GetThumbnail());

                                    cameraRollImages.Items.Add(new PictureItem
                                    {
                                        ThumbUrl = b,
                                        ThumbStream = p.GetThumbnail(),
                                        ImageStream = p.GetImage(),
                                        OriginalFileName = p.Name,
                                        Date = p.Date
                                    });
                                }
                                _currentIndex = _currentIndex - _loadThreadhold;

                                progressString.Visibility = Visibility.Collapsed;
                                lls_camera_roll.ItemsSource = cameraRollImages.Items;

                                if (selectedPics.Items.Count == 0)
                                    return;

                                SetSelectedPhoto();
                            });
                        }
                    }
                }
            }).Start();
        }

        private void SetSelectedPhoto()
        {
            List<PictureItem> items = new List<PictureItem>();

            foreach (PictureItem item in lls_camera_roll.ItemsSource)
            {
                foreach (var selectedItem in selectedPics.Items)
                {
                    if (item.Date == selectedItem.Date)
                    {
                        items.Add(item);
                    }
                }
            }

            lls_camera_roll.SelectedItems.Clear();

            foreach (var picture in items)
            {
                lls_camera_roll.SelectedItems.Add(picture);
            }
        }

        private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (pivot.SelectedIndex == 2)
            {
                lls_saved_picture.ItemsSource = null;
                lls_saved_picture.ItemsSource = selectedPics.Items;
            }
            
        }

        private void lls_camera_roll_ItemRealized(object sender, ItemRealizationEventArgs e)
        {
            lock (o)
            {
                if (!IsLoading)
                {
                    if (e.ItemKind == LongListSelectorItemKind.Item)
                    {
                        if ((e.Container.Content as PictureItem).Equals(lls_camera_roll.ItemsSource[lls_camera_roll.ItemsSource.Count - 1]))
                        {
                            IsLoading = true;
                            Microsoft.Phone.Shell.ProgressIndicator progressIndicator = new Microsoft.Phone.Shell.ProgressIndicator();
                            Microsoft.Phone.Shell.SystemTray.ProgressIndicator = progressIndicator;
                            progressIndicator.Text = "Loading...";
                            progressIndicator.IsIndeterminate = true;
                            progressIndicator.IsVisible = true;

                            int deviateCount = _currentIndex - _loadThreadhold;
                           
                            if (deviateCount > _loadThreadhold)
                            {
                                //Load threadHold
                                for (int i = _currentIndex; i > _currentIndex - _loadThreadhold; i--)
                                {
                                    Picture p = cameraRoll.Pictures[i];
                                    BitmapImage b = new BitmapImage();
                                    b = new BitmapImage();
                                    b.CreateOptions = BitmapCreateOptions.BackgroundCreation;
                                    b.SetSource(p.GetThumbnail());

                                    cameraRollImages.Items.Add(new PictureItem
                                    {
                                        ThumbUrl = b,
                                        ThumbStream = p.GetThumbnail(),
                                        ImageStream = p.GetImage(),
                                        OriginalFileName = p.Name,
                                        Date = p.Date
                                    });
                                }

                                _currentIndex = _currentIndex - _loadThreadhold;
                            }
                            else if (deviateCount < 0 && deviateCount != - _loadThreadhold)
                            { 
                                //Load rest
                                for (int i = _currentIndex; i > -1; i--)
                                {
                                    Picture p = cameraRoll.Pictures[i];
                                    BitmapImage b = new BitmapImage();
                                    b = new BitmapImage();
                                    b.CreateOptions = BitmapCreateOptions.BackgroundCreation;
                                    b.SetSource(p.GetThumbnail());

                                    cameraRollImages.Items.Add(new PictureItem
                                    {
                                        ThumbUrl = b,
                                        ThumbStream = p.GetThumbnail(),
                                        ImageStream = p.GetImage(),
                                        OriginalFileName = p.Name,
                                        Date = p.Date
                                    });
                                }
                                _currentIndex = 0;
                            }
                            else
                            {
                                //Do nothing
                            }

                            SetSelectedPhoto();
                            progressIndicator.IsVisible = false;
                            IsLoading = false;
                        }
                    }
                }
            }
        }
    }
}